{% extends "admin/base_site_grid.html" %}
{% load i18n %}

{% block tools %}
{% include "common/snippet_follow.html" %}
{{block.super}}
{% endblock %}

{% block tabs %}
{% tabs "input.calendar" %}
{% endblock %}

{% block before_table %}
<div class="row">
  <div id="focusgraph" style="clear: both; height: 200px; padding: 10px"></div>
</div>
<div class="row">
  <div id="contextgraph" style="clear: both; height: 50px; padding: 10px"></div>
</div>
{% endblock %}

{% block table %}
{% if hasaddperm %}
<form>
  <div class="row mt-1 gy-3 align-items-center flex-wrap justify-content-evenly" style="max-width: 1400px">
    <div class="col-auto d-flex align-items-center">
      <div class="d-inline-block me-3">
        <button class="btn btn-primary d-block" id="add_button" disabled>{% trans "Add"|capfirst %}</button>
      </div>
      <div class="d-inline-block me-2">
        <input type="datetime-local" class="form-control w-auto" id="add_start_date">
        <div class="mt-1 help-block">{% trans "start date"|capfirst %}</div>
      </div>
      <div class="d-inline-block me-2">
        <input type="datetime-local" class="form-control w-auto" id="add_end_date">
        <div class="mt-1 help-block">{% trans "end date"|capfirst %}</div>
      </div>
      <div class="d-inline-block me-2">
        <input type="number" style="width: 6em" class="form-control d-inline" id="add_value">
        <div class="mt-1 help-block">{% trans "value"|capfirst %}</div>
      </div>
    </div>
    <div class="col-auto d-flex align-items-center">
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_monday" checked>
        <div class="mt-1 help-block">&nbsp;{% trans "monday"|capfirst %}&nbsp;</div>
      </div>
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_tuesday" checked>
        <div class="mt-1 help-block">&nbsp;{% trans "tuesday"|capfirst %}&nbsp;</div>
      </div>
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_wednesday" checked>
        <div class="mt-1 help-block">&nbsp;{% trans "wednesday"|capfirst %}&nbsp;</div>
      </div>
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_thursday" checked>
        <div class="mt-1 help-block">&nbsp;{% trans "thursday"|capfirst %}&nbsp;</div>
      </div>
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_friday" checked>
        <div class="mt-1 help-block">{% trans "friday"|capfirst %}&nbsp;</div>
      </div>
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_saturday" checked>
        <div class="mt-1 help-block">&nbsp;{% trans "saturday"|capfirst %}&nbsp;</div>
      </div>
      <div class="d-inline-block" style="text-align:center">
        <input class="form-check-input" type="checkbox" id="add_sunday" checked>
        <div class="mt-1 help-block">&nbsp;{% trans "sunday"|capfirst %}&nbsp;</div>
      </div>
    </div>
    <div class="col-auto d-flex align-items-center">
      <div class="d-inline-block ms-2  me-2">
        <input type="time" class="form-control" id="add_start_time" value="00:00:00">
        <div class="mt-1 help-block">{% trans "start time"|capfirst %}</div>
      </div>
      <div class="d-inline-block">
        <input type="time" class="form-control" id="add_end_time" value="23:59:59">
        <div class="mt-1 help-block">{% trans "end time"|capfirst %}</div>
      </div>
    </div>
  </div>
</form>
{% endif %}
{{ block.super }}
{% endblock %}

{% block extrahead %}{{block.super}}
<script src="{{STATIC_URL}}js/d3.min.js"></script>
<script>
var events = {{events|json}};
var horizonstart = new Date({{request.report_startdate|date:"Y"}},{{request.report_startdate|date:"n"}}-1,{{request.report_startdate|date:"j"}});
var horizonend = new Date({{request.report_enddate|date:"Y"}},{{request.report_enddate|date:"n"}}-1,{{request.report_enddate|date:"j"}});
var viewstart = new Date(horizonstart.getTime());
var viewend = new Date((horizonstart.getTime() + horizonend.getTime()) / 2);

var min_y = 0;
var max_y = 0;
var min_x;
var max_x;

var brush;
var zoom;
var zoom_start;
var zoom_end;

$(function() {
    $("#save").attr("onclick", "upload.save(function() {window.location.href = window.location.href})");
{% if hasaddperm %}
    updateAddForm();
    $("#add_value").on("input", function() {
      $("#add_button").attr("disabled", $(this).val() == "");
    });
    $("#add_button").on("click", function(event) {
      event.preventDefault();
      event.stopImmediatePropagation();
      data = [{
          "calendar": "{{calendar|escapejs}}",
          "startdate": $("#add_start_date").val(),
          "enddate": $("#add_end_date").val(),
          "value": $("#add_value").val(),
          "priority": {{minpriority}},
          "monday": $("#add_monday").is(":checked"),
          "tuesday": $("#add_tuesday").is(":checked"),
          "wednesday": $("#add_wednesday").is(":checked"),
          "thursday": $("#add_thursday").is(":checked"),
          "friday": $("#add_friday").is(":checked"),
          "saturday": $("#add_saturday").is(":checked"),
          "sunday": $("#add_sunday").is(":checked"),
          "starttime": $("#add_start_time").val(),
          "endtime": $("#add_end_time").val(),
      }];
      $.ajax({
        url: url_prefix + "/api/input/calendarbucket/",
        data: JSON.stringify(data),
        type: "POST",
        contentType: "application/json",
        success: function () {
          window.location.href = window.location.href;
        },
        error: ajaxerror
      });
    });
{% endif %}
});

{% if hasaddperm %}
function updateAddForm() {
  var tmp = viewstart.getFullYear() + "-"
       + ("0" + (viewstart.getMonth() + 1)).slice(-2) + "-"
       + ("0" + viewstart.getDate()).slice(-2) + "T00:00";
  $("#add_start_date").prop("value", tmp);
  tmp = viewend.getFullYear() + "-"
       + ("0" + (viewend.getMonth() + 1)).slice(-2) + "-"
       + ("0" + viewend.getDate()).slice(-2) + "T00:00";
  $("#add_end_date").prop("value", tmp);
}
{% endif %}

function drawContextGraph() {
    var width = $("#contextgraph").width();
    var height = $("#contextgraph").height();

    $("#contextgraph").html("");
    var svg = d3.select($("#contextgraph").get(0))
      .append("svg")
      .attr("width", width)
      .attr("height", height);

    for (var e of events) {
      e[0] = new Date(e[0]);
      e[1] = new Date(e[1]);
      if (!min_x) min_x = e[0];
      max_x = e[1];
      if (e[3] < min_y) min_y = e[3];
      if (e[3] > max_y) max_y = e[3];
      if (e[5] < min_y) min_y = e[5];
      if (e[5] > max_y) max_y = e[5];      
    }
    var x = d3.scale.linear().rangeRound([50, width]).domain([min_x, max_x]);
    var y = d3.scale.linear().rangeRound([0, height]).domain([max_y, min_y]);

    // Build line graph data
    var linedata = [];
    var last_y = null;
    var last_x = 0;
    for (var d of events) {
      if (last_y === null) {
        linedata.push([x(viewstart), y(0)]);
        last_y = y(d[5]);
        linedata.push([x(viewstart), last_y]);
      }
      var tmp_x = x(d[1]);
      linedata.push([tmp_x, (last_y !== null) ? last_y : y(min_y)]);
      last_y = y(d[3]);
      linedata.push([tmp_x, last_y]);
      last_x = tmp_x;
    }
    linedata.push([last_x, y(0)]);
    linedata.push([x(horizonstart), y(0)]);

    // Draw line graph
    var line = d3.svg.line()
        .x(function(d) { return d[0]; })
        .y(function(d) { return d[1]; });
    svg.append("svg:path")
        .attr("stroke","#8BBA00")
        .attr("fill","#8BBA00")
        .attr("stroke-width", 0)
        .attr("d", line(linedata));

    // Draw brush
    brush = d3.svg.brush()
        .x(x)
        .extent([viewstart, viewend])
        .on("brush", function() {
           if (brush.empty()) {
             viewstart = horizonstart;
             viewend = horizonend;
           } else {
              var tmp = brush.extent();
              viewstart = new Date(tmp[0]);
              viewend = new Date(tmp[1]);
           }
           drawFocusGraph();
           {% if hasaddperm %}updateAddForm();{% endif %}
        });
    var brushg = svg.append("g").call(brush);
    brushg.selectAll(".extent")
      .attr("x", x(viewstart))
      .attr("width", x(viewend) - x(viewstart))
      .attr("y", height /4)
      .attr("fill", "gray")
      .attr("opacity", 0.4)
      .attr("height", height / 2);
    brushg.selectAll(".resize")
        .append("rect")
        .attr("width", 6)
        .attr("fill", "gray")
        .attr("transform", "translate(-2," + height/4 + ")")
        .attr('rx', 2)
        .attr('ry', 2)
        .attr("height", height / 2)
        .attr("width", 4);
}

function drawFocusGraph() {
    var width = $("#focusgraph").width();
    var height = $("#focusgraph").height();

    var selectedRows = $("#grid").jqGrid("getGridParam", "selarrrow");

    $("#focusgraph").html("");
    var svg = d3.select($("#focusgraph").get(0))
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(50,0)");

    svg.append("defs").append("clipPath")
      .attr("id", "clip")
      .append("rect")
      .attr("width", width-50)
      .attr("height", height)-20;

    var x = d3.scale.linear().rangeRound([0, width - 50]).domain([viewstart, viewend]);
    var y = d3.scale.linear().rangeRound([0, height - 20]).domain([max_y, min_y]);

    // Build line graph
    var linedata = [];
    var last_y = null;
    var last_x = 0;
    for (var d of events) {
      var tmp_x = x(d[1]);
      if (last_y === null) {
        linedata.push([x(viewstart), y(0)]);
        last_y = y(d[5]);
        linedata.push([x(viewstart), last_y]);
      }
      linedata.push([tmp_x, (last_y !== null) ? last_y : y(min_y)]);
      last_y = y(d[3]);
      linedata.push([tmp_x, last_y]);
      last_x = tmp_x;
    };
    linedata.push([last_x, y(0)]);
    linedata.push([x(viewstart), y(0)]);
    var line = d3.svg.line()
        .x(function(d) { return d[0]; })
        .y(function(d) { return d[1]; });
    svg.append("svg:path")
        .attr("stroke","#E68BBA00")
        .attr("stroke-width", 0)
        .attr("fill","#8BBA00")
        .attr("clip-path", "url(#clip)")
        .attr("d", line(linedata));

    // Build tooltips
    last_x = 0;
    svg.selectAll("g")
      .data(events)
      .enter()
      .append("rect")
      .filter(function(d) { return d[1] >= viewstart && d[0] <= viewend; })
           .attr("x", function(d) { return x(d[0]); })
           .attr("width", function(d) { return x(d[1]) - x(d[0]); })
           .attr("y", 0)
           .attr("fill", "black")
           .attr("height", height-20)
           .attr("opacity", function(d) { return selectedRows.includes("" + d[4]) ? 0.2 : 0;})
           .attr("clip-path", "url(#clip)")
           .on("mouseenter", function(d) {
              jQuery("#grid").jqGrid('resetSelection');
              if (d[4]) jQuery("#grid").jqGrid('setSelection', d[4], false);
              if (d[4])
                graph.showTooltip(interpolate(
                  gettext("Between %s<br>and %s<br>the entry %s<br>sets value %s"),
                  [
                    moment(d[0]).format(datetimeformat),
                    moment(d[1]).format(datetimeformat),
                    d[4],
                    d[5]
                  ]
                  ));
              else
                  graph.showTooltip(interpolate(
                  gettext("Between %s<br>and %s<br>the default value %s is set"),
                  [
                    moment(d[0]).format(datetimeformat),
                    moment(d[1]).format(datetimeformat),
                    d[5]
                  ]
                  ));
             })
	         .on("mouseleave", graph.hideTooltip)
	         .on("mousemove", graph.moveTooltip);

    // Display Y-Axis
    var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(4)
      .tickFormat(d3.format("s"));
    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

    // Display X-Axis
    var ticks = [];
    var tickinterval = Math.max((viewend - viewstart) / 10, 86400000);
    var tick = new Date(viewstart.getTime() + 86400000);
    while(tick < viewend) {
      tick = new Date(tick.getFullYear(), tick.getMonth(), tick.getDate());
      ticks.push(tick);
      tick = new Date(tick.getTime() + tickinterval);
    }
    var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .tickValues(ticks)
      .tickFormat(function(d, i) {
        var v = new Date(d);
        return moment(v).format(dateformat);
      });
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + (height - 20) + ")")
      .call(xAxis);

    // Zoom & scroll behavior
    zoom = d3.behavior.zoom()
        .x(x)
        .on("zoom", function(arg) {
          var initial_range = zoom_end.getTime() - zoom_start.getTime();
          var delta_range = initial_range / d3.event.scale - initial_range;
          var translate_range = 0; // TODO d3.event.translate[0] / x.range()[1] * initial_range;
          viewstart = new Date(zoom_start.getTime() - delta_range / 2 + translate_range);
          viewend = new Date(zoom_end.getTime() + delta_range / 2 + translate_range);
          if (viewstart < horizonstart)
             viewstart = horizonstart;
          if (viewend > horizonend)
             viewend = horizonend;
          brush.extent([viewstart, viewend]);
          drawContextGraph();
          drawFocusGraph();
          {% if hasaddperm %}updateAddForm();{% endif %}
        })
        .on("zoomstart", function() {
          zoom_start = viewstart;
          zoom_end = viewend;
        });
    svg.call(zoom);
}

function initGraphs(jsondata) {
  drawContextGraph();
  drawFocusGraph();
}

$(window).resize(initGraphs);

</script>
{% endblock %}

{% block extra_grid %}
  loadComplete: initGraphs,
  onSelectRow: function(rowid, status, e) {
      var selection = $(this).jqGrid('getGridParam','selarrrow').slice(); //this makes this list a static list of values
      grid.markSelectedRow(selection.length);
      drawFocusGraph();
  },
  onSelectAll: drawFocusGraph,
{% endblock %}
